//
// Created by martin on 2/17/22.
//

#ifndef MUDUO_WEAKCALLBACK_H
#define MUDUO_WEAKCALLBACK_H

#include <functional>
#include <memory>

namespace muduo
{

/* A barely usable WeakCallback */

/**
 * 以一种安全方式调用 形如 function(object, ...), 如果object指向一个class, 那么相当于即object->function()
 */
template<typename CLASS, typename... ARGS> // ARGS是可变参数模板参数包
class WeakCallback
{
public:
    WeakCallback(const std::weak_ptr<CLASS>& object, //　weak_ptr安全地使用传入实參
                 const std::function<void (CLASS*, ARGS...)>& function) // function参数个数不确定
                 : object_(object), function_(function)
    {
    }

    // Default dtor, copy ctor and assignment are okay

    void operator()(ARGS&&... args) const // args参数包
    {
        // 安全地使用weak_ptr所指对象
        std::shared_ptr<CLASS> ptr(object_.lock()); // 先lock, 再提升为shared_ptr, 只在local作用域影响引用计数
        if (ptr)
        {
            function_(ptr.get(), std::forward<ARGS>(args)...);
        }
//        else
//        {
//            LOG_TRACE << "expired";
//        }
    }

private:
    std::weak_ptr<CLASS> object_;
    std::function<void (CLASS*, ARGS...)> function_;
};

/* 制造一个临时WeakCallback对象, 便于调用object->function(...) */
template<typename CLASS, typename... ARGS>
WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
                                              void (CLASS::*function)(ARGS...))
{
    return WeakCallback<CLASS, ARGS...>(object, function);
}

/* 制造一个临时WeakCallback对象, 便于调用object->function(...) const */
template<typename CLASS, typename ... ARGS>
WeakCallback<CLASS, ARGS...> makeWeakCallback(const std::shared_ptr<CLASS>& object,
                                              void (CLASS::*function)(ARGS...) const)
{
    return WeakCallback<CLASS, ARGS...>(object, function);
}

} // namespace muduo

#endif //MUDUO_WEAKCALLBACK_H
